1
/****************************** Module Header ******************************\
2 Module Name: WordDocumentImageManipulator.cs
3 Project: CSManipulateImagesInWordDocument
4 Copyright (c) Microsoft Corporation.
6 The class WordDocumentImageManipulator is used to export, delete or replace
7 the images in a word document.
9 The image data in a document are stored as a ImagePart, and the Blip element
10 in a Drawing element will refers to the ImagePart. Different Blip elements may
11 refer to the same ImagePart.
13 To delete/replace the images in a document, we need to edit the Blip/Drawing
17 This source is subject to the Microsoft Public License.
18 See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
19 All other rights reserved.
21 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
22 EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
24 \***************************************************************************/
27 using System
.Collections
.Generic
;
31 using DocumentFormat
.OpenXml
;
32 using DocumentFormat
.OpenXml
.Drawing
;
33 using DocumentFormat
.OpenXml
.Packaging
;
34 using DocumentFormat
.OpenXml
.Wordprocessing
;
36 namespace CSManipulateImagesInWordDocument
38 public class WordDocumentImageManipulator
: IDisposable
40 bool disposed
= false;
42 // Occured when an image is deleted or replaced.
43 public event EventHandler ImagesChanged
;
45 // The WordprocessingDocument instance.
46 public WordprocessingDocument Document { get; private set; }
49 /// Initialize the WordDocumentImageManipulator instance.
51 /// <param name="path">
52 /// The document file path.
54 public WordDocumentImageManipulator(FileInfo path
)
57 // Open the document as editable.
58 Document
= WordprocessingDocument
.Open(path
.FullName
, true);
63 /// Get all images in the documents.
64 /// The image in a document is stored as a Blip element.
66 /// <returns></returns>
67 public IEnumerable
<Blip
> GetAllImages()
70 // Get the drawing elements in the document.
71 var drawingElements
= from run
in Document
.MainDocumentPart
.Document
.Descendants
<DocumentFormat
.OpenXml
.Wordprocessing
.Run
>()
72 where run
.Descendants
<Drawing
>().Count() != 0
73 select run
.Descendants
<Drawing
>().First();
75 // Get the blip elements in the drawing elements.
76 var blipElements
= from drawing
in drawingElements
77 where drawing
.Descendants
<Blip
>().Count() > 0
78 select drawing
.Descendants
<Blip
>().First();
84 /// Get the image from the Blip element.
86 public Image
GetImageInBlip(Blip blipElement
)
89 // Get the ImagePart referred by the Blip element.
90 var imagePart
= Document
.MainDocumentPart
.GetPartById(blipElement
.Embed
.Value
)
93 if (imagePart
!= null)
95 using (Stream imageStream
= imagePart
.GetStream())
97 Bitmap img
= new Bitmap(imageStream
);
103 throw new ApplicationException("Can not find image part : "
104 + blipElement
.Embed
.Value
);
109 /// Delete the Drawing element that contains the Blip element.
111 /// <param name="blipElement"></param>
112 public void DeleteImage(Blip blipElement
)
114 OpenXmlElement parent
= blipElement
.Parent
;
115 while (parent
!= null &&
116 !(parent
is DocumentFormat
.OpenXml
.Wordprocessing
.Drawing
))
118 parent
= parent
.Parent
;
123 Drawing drawing
= parent
as Drawing
;
124 drawing
.Parent
.RemoveChild
<Drawing
>(drawing
);
126 // Raise the ImagesChanged event.
127 this.OnImagesChanged();
133 /// To replace an image in a document
134 /// 1. Add an ImagePart to the document.
135 /// 2. Edit the Blip element to refer to the new ImagePart.
137 /// <param name="blipElement"></param>
138 /// <param name="newImg"></param>
139 public void ReplaceImage(Blip blipElement
, FileInfo newImg
)
141 string rid
= AddImagePart(newImg
);
142 blipElement
.Embed
.Value
= rid
;
143 this.OnImagesChanged();
147 /// Add ImagePart to the document.
149 string AddImagePart(FileInfo newImg
)
151 ImagePartType type
= ImagePartType
.Bmp
;
152 switch(newImg
.Extension
.ToLower())
156 type
= ImagePartType
.Jpeg
;
159 type
= ImagePartType
.Png
;
162 type
= ImagePartType
.Bmp
;
166 ImagePart newImgPart
= Document
.MainDocumentPart
.AddImagePart(type
);
167 using (FileStream stream
= newImg
.OpenRead())
169 newImgPart
.FeedData(stream
);
172 string rId
= Document
.MainDocumentPart
.GetIdOfPart(newImgPart
);
178 /// Raise the ImagesChanged event.
180 protected virtual void OnImagesChanged()
182 if (this.ImagesChanged
!= null)
184 this.ImagesChanged(this, EventArgs
.Empty
);
188 public void Dispose()
191 GC
.SuppressFinalize(this);
194 protected virtual void Dispose(bool disposing
)
196 // Protect from being called multiple times.
204 if (Document
!= null)